added SSCLI 1.0
[windows-sources.git] / shared source / sscli20 / samples / compilers / myc / src / io.cs
blob68490abf9d030de565de634b94ca9a3b7c803e65
1 //------------------------------------------------------------------------------
2 // <copyright file="io.cs" company="Microsoft">
3 //
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
5 //
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
10 //
11 // You must not remove this notice, or any other, from this software.
12 //
13 // </copyright>
14 //------------------------------------------------------------------------------
16 namespace MyC
18 using System;
19 using System.Text;
20 using System.IO;
21 #if EXEGEN
22 using System.Reflection;
23 #endif
25 class Io
27 private FileStream ifile;
28 private StreamReader rfile;
30 private FileStream lst_ofile;
31 private StreamWriter lst_wfile;
33 private static String ifilename;
34 private static String ofilename;
35 private static String lst_ofilename;
36 private static String classname;
38 public static bool gendebug = false;
39 public static bool genexe = true; // default to generating exe's
40 public static bool gendll = false;
41 public static bool genlist = false;
42 public static string genpath = "."; // default output directory to current dir
44 private String[] args;
45 private char[] ibuf;
47 private int ibufidx;
48 private int ibufread;
49 private bool _eof;
51 /* variable declarations */
52 private char look; /* lookahead character */
53 private StringBuilder buf; /* buffer for comment tracking */
54 int bufline = 0; // current line matching buffer
55 int curline = 0; // current comment line number
57 public static string GetClassname()
59 return classname;
62 public String GetInputFilename()
64 return ifilename;
66 /* read new character from input stream */
67 public void ReadChar()
69 if (_eof) // if already eof, nothing to do here
70 return;
71 if (ibuf == null || ibufidx >= MyC.MAXBUF)
73 ibuf = new char[MyC.MAXBUF];
74 _eof = false;
75 ibufread = rfile.Read(ibuf, 0, MyC.MAXBUF);
76 ibufidx = 0;
77 if (buf == null)
78 buf = new StringBuilder(MyC.MAXSTR);
80 look = ibuf[ibufidx++];
81 if (ibufread < MyC.MAXBUF && ibufidx > ibufread)
82 _eof = true;
85 * track the read characters
87 buf.Append(look);
88 if (look == '\n')
89 bufline++;
92 public char getNextChar()
94 return look;
97 public void Abort(string s)
99 StringBuilder sb = new StringBuilder();
100 sb.Append(ifilename);
101 sb.Append("(");
102 sb.Append(curline+1);
103 sb.Append(") : error M0000: ");
104 sb.Append(s);
105 Console.WriteLine(sb.ToString());
106 throw new ApplicationException("Aborting compilation");
109 public static void ICE(string s) // internal compiler error
111 StringBuilder sb = new StringBuilder();
112 sb.Append(ifilename);
113 sb.Append("(0) : error M9999: Internal Compiler Error: ");
114 sb.Append(s);
115 Console.WriteLine(sb.ToString());
116 throw new ApplicationException("Aborting compilation");
119 void ParseArgs()
121 int i = 1;
123 if (args.Length < 2)
125 Abort("myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
128 while (true)
130 if (args[i][0] != '/')
131 break;
132 if (args[i].Equals("/?"))
134 Console.WriteLine("Compiler options:\n myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
135 Environment.Exit(1);
137 if (args[i].Equals("/debug"))
139 gendebug = true;
140 i++;
141 continue;
143 if (args[i].Equals("/nodebug"))
145 gendebug = false;
146 i++;
147 continue;
149 if (args[i].Equals("/exe"))
151 genexe = true;
152 gendll = false;
153 i++;
154 continue;
156 if (args[i].Equals("/dll"))
158 gendll = true;
159 genexe = false;
160 i++;
161 continue;
163 if (args[i].Equals("/list"))
165 genlist = true;
166 i++;
167 continue;
169 if (args[i].Length > 8 && args[i].Substring(0,8).Equals("/outdir:"))
171 genpath = args[i].Substring(8);
172 i++;
173 continue;
176 * exit if no switch matched
178 Abort("Unmatched switch = '"+args[i]+"'\nArguments are:\nmyc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
181 if (args.Length-i != 1)
183 Abort("myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
185 ifilename = args[args.Length-1]; // filename is last
188 public Io(String[] a)
190 int i;
192 args = a;
193 ParseArgs();
195 ifile = new FileStream(ifilename, FileMode.Open,
196 FileAccess.Read, FileShare.Read, 8192);
197 if (ifile == null)
199 Abort("Could not open file '"+ifilename+"'\n");
201 rfile = new StreamReader(ifile); // open up a stream for reading
204 * for now we are going to create a default class using the filename
206 i = ifilename.LastIndexOf('.');
207 if (i < 0)
208 Abort("Bad filename '"+ifilename+"'");
209 int j = ifilename.LastIndexOf('\\');
210 if (j < 0)
211 j = 0;
212 else
213 j++;
215 classname = ifilename.Substring(j,i-j);
216 if (genexe)
217 ofilename = classname+".exe";
218 if (gendll)
219 ofilename = classname+".dll";
220 if (genlist)
222 lst_ofilename = classname+".lst";
223 lst_ofile = new FileStream(lst_ofilename, FileMode.Create,
224 FileAccess.Write, FileShare.Write, 8192);
225 if (lst_ofile == null)
226 Abort("Could not open file '"+ofilename+"'\n");
227 lst_wfile = new StreamWriter(lst_ofile);
231 public void Out(String s)
233 lst_wfile.Write(s); // write the buffer
234 lst_wfile.Flush(); // slow, but useful
237 public void Finish()
239 rfile.Close();
240 ifile.Close();
241 if (genlist)
243 lst_wfile.Close();
244 lst_ofile.Close();
248 public bool EOF()
250 return _eof;
254 public String commentEndPreTok(String s)
256 #if DEBUG
257 Console.Write("commentEndPreTok1 S=["+s+"], buf=");
258 for (int _debug_i=0; _debug_i<buf.Length;_debug_i++)
260 int _debug_d = buf[_debug_i];
261 char _debug_c = (char) (_debug_d + 96);
262 if (_debug_d < 32)
263 Console.Write("^"+Char.ToString(_debug_c));
264 else
265 Console.Write(buf[_debug_i]);
266 Console.Write("[");
267 Console.Write(_debug_d);
268 Console.Write("],");
270 Console.WriteLine(";");
271 #endif
273 * many times we will already have parsed source code past the point
274 * that we want to emit. We will use the token given to backup.
276 String b;
277 if (s == null) // make sure we have something
278 return null;
279 b = buf.ToString(); // have to convert first
280 int i = b.LastIndexOf(s); // find this token in buffer
281 String c = b.Substring(0,i).Trim(); // copy as comment
282 buf = new StringBuilder(b.Substring(i), MyC.MAXSTR); // remake buffer
284 * need to update curline to be in synch with last emitted comment
286 curline = bufline;
287 for (int ci = 0; ci < buf.Length; ci++)
288 if (buf[ci] == '\n')
289 curline--;
290 #if DEBUG
291 Console.Write("commentEndPreTok2 buf=");
292 for (int _debug_i=0; _debug_i<buf.Length;_debug_i++)
294 int _debug_d = buf[_debug_i];
295 char _debug_c = (char) (_debug_d + 96);
296 if (_debug_d < 32)
297 Console.Write("^"+_debug_c);
298 else
299 Console.Write(buf[_debug_i]);
300 Console.Write("[");
301 Console.Write(_debug_d);
302 Console.Write("],");
304 Console.WriteLine(";");
305 #endif
306 return c;
309 public String commentEndTok(String s)
311 #if DEBUG
312 Console.Write("commentEndTok1 S=["+s+"], buf=");
313 for (int _debug_i=0; _debug_i<buf.Length;_debug_i++)
315 int _debug_d = buf[_debug_i];
316 char _debug_c = (char) (_debug_d + 96);
317 if (_debug_d < 32)
318 Console.Write("^"+_debug_c);
319 else
320 Console.Write(buf[_debug_i]);
321 Console.Write("[");
322 Console.Write(_debug_d);
323 Console.Write("],");
325 Console.WriteLine(";");
326 #endif
329 * variant to include this token at end of comment
331 String b;
332 if (s == null) // make sure we have something
333 return null;
334 b = buf.ToString(); // have to convert first
335 int i = b.LastIndexOf(s); // find this token in buffer
336 String c = b.Substring(0,i+s.Length).Trim(); // copy as comment
337 buf = new StringBuilder(b.Substring(i+s.Length), MyC.MAXSTR); // remake buffer
339 * need to update curline to be in synch with last emitted comment
341 curline = bufline;
342 for (int ci = 0; ci < buf.Length; ci++)
343 if (buf[ci] == '\n')
344 curline--;
345 #if DEBUG
346 Console.Write("commentEndTok2 buf=");
347 for (int _debug_i=0; _debug_i<buf.Length;_debug_i++)
349 int _debug_d = buf[_debug_i];
350 char _debug_c = (char) (_debug_d + 96);
351 if (_debug_d < 32)
352 Console.Write("^"+_debug_c);
353 else
354 Console.Write(buf[_debug_i]);
355 Console.Write("[");
356 Console.Write(_debug_d);
357 Console.Write("],");
359 Console.WriteLine(";");
360 #endif
361 return c;
364 public void commentBegin(String s)
366 String b;
367 if (s == null) // make sure we have something
368 return;
369 b = buf.ToString(); // have to convert first
370 int i = b.IndexOf(s); // find this token in buffer
371 if (i < 0)
372 i = b.Length; // if not found, use whole string
373 buf = new StringBuilder(b.Substring(i), MyC.MAXSTR); // remake buffer from substr
375 * need to update curline to be in synch with last emitted comment
377 curline = bufline;
378 for (int ci = 0; ci < buf.Length; ci++)
379 if (buf[ci] == '\n')
380 curline--;
381 #if DEBUG
382 Console.Write("commentBegin S=["+s+"], buf=");
383 for (int _debug_i=0; _debug_i<buf.Length;_debug_i++)
385 int _debug_d = buf[_debug_i];
386 char _debug_c = (char) (_debug_d + 96);
387 if (_debug_d < 32)
388 Console.Write("^"+_debug_c);
389 else
390 Console.Write(buf[_debug_i]);
391 Console.Write("[");
392 Console.Write(_debug_d);
393 Console.Write("],");
395 Console.WriteLine(";");
396 #endif
399 public int commentGetCurrentLine()
401 return curline+1;
404 public static string GetOutputFilename()
406 return ofilename;